Skip to content

Revised POMDP belief exploration - #1004

Open
AlexBork wants to merge 64 commits into
stormchecker:masterfrom
AlexBork:revised-belief-merge
Open

AlexBork wants to merge 64 commits into
stormchecker:masterfrom
AlexBork:revised-belief-merge

Conversation

@AlexBork

@AlexBork AlexBork commented Aug 11, 2026 •

Copy link
Copy Markdown
Contributor

This PR contains the revised POMDP belief exploration implementation.
The revised implementation is more modular, making it easier to add extensions.
In addition, it is more performant than the old one.

This PR also adds the functionality to analyse reward-bounded reachability properties on POMDP, as described in https://proceedings.mlr.press/v286/bork25a.html

The revised implementation is fully replacing the current one.
Wo do not port over all functionality from the old implementation.

Changes outside of Storm-POMDP are part of separate PR #1028

@sjunges sjunges added this to the 1.15 milestone Aug 12, 2026
@sjunges

sjunges commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

What besides SAYNT may depend on the old one? I understand the desire to treat carefully, but I also think it may simplify the merging process significantly if we do hard cut. People that want the old version will need to work with 1.14 and as long as it is clear what features we are loosing, that all seems fine to me.

@AlexBork

Copy link
Copy Markdown
Contributor Author

I can't think of anything that depends on the old one besides SAYNT. Featurewise, I think the only significant omission currently is the automated refinement loop for the approximations. I think that needs some conceptual reworking before implementation, so I have omitted it for now.

All in all, I would be fine with completely removing the old implementation. As we are reworking SAYNT, there should be no reason for keeping it.

@sjunges

sjunges commented Aug 17, 2026

Copy link
Copy Markdown
Contributor

Would it make sense to split this PR into one that touches storm and one that only touches storm-pomdp? Also, within storm-pomdp, I was wondering whether some parts of the CLI should actually be moved into their own header/cpp (pomdp-handling.h) or so such that it is a bit clearer where it is just cli handling and where it is configuring the algorithm?

@AlexBork

Copy link
Copy Markdown
Contributor Author

I'll split the PR. That definitely makes things more manageable.
The CLI handling also sounds reasonable. I'll look into it if I find some time.

@tquatmann tquatmann left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I haven't finished my review yet but here are my comments so far :)

Comment thread src/storm-pomdp-cli/settings/modules/POMDPSettings.cpp Outdated
Comment thread src/storm-pomdp/transformer/RewardBoundUnfolder.h Outdated
Comment thread src/storm/transformer/SparseModelToDoubleTransformer.h Outdated
* Zero level widths unfold a dimension completely and remove its bound. Positive level widths retain a compact
* epoch representation and introduce a corresponding level reward model.
*/
static ReturnType transform(storm::models::sparse::Model<ValueType> const& model, storm::logic::Formula const& formula,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Create a test case for this transformation. Should also work for DTMC/MDP (not just POMDP) right?

template<typename ValueType>
RewardBoundUnfolder<ValueType>::ReturnType RewardBoundUnfolder<ValueType>::transform(storm::models::sparse::Model<ValueType> const& model,
storm::logic::Formula const& formula, UnfoldingOptions const& options) {
if (formula.isProbabilityOperatorFormula()) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Throw for certain model files? Only DTMC, MDP, POMDP should work.

// Generated observations must not collide with the original observations retained by initial-state copies.
ObservationType freshObservation = pomdp.getNrObservations();
auto getOrAddObservationIndex = [&observationIndexStorage, &freshObservation](TransitionObservation const& obs) {
auto [it, inserted] = observationIndexStorage.try_emplace(obs, freshObservation);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is try_emplace correct here?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I think so. We want to get the entry, which we get via the iterator it and insert a new value if it is not already in the map. What do you think may be a problem here?

Comment thread src/storm-pomdp/storage/BeliefExplorationResult.h Outdated
Comment thread src/storm-pomdp/storage/BeliefExplorationResult.h Outdated
Comment thread src/storm-pomdp/storage/BeliefExplorationResult.h Outdated

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment thread src/storm-pomdp/beliefs/exploration/BeliefMdpBuilder.cpp
Comment on lines +324 to +334
if (isRewBndReachProb) {
stateLabeling.addLabelToState("target", targetState);
for (auto const& [belId, state] : explorationInformation.exploredBeliefs) {
if (propertyInformation.targetObservations.contains(explorationInformation.discoveredBeliefs.getBeliefFromId(belId).observation() %
explorationInformation.nrObservationsInPomdp)) {
stateLabeling.addLabelToState("target", state);
}
}
for (auto const& belId : frontierBeliefs) {
if (propertyInformation.targetObservations.contains(explorationInformation.discoveredBeliefs.getBeliefFromId(belId).observation() %
explorationInformation.nrObservationsInPomdp)) {
Comment on lines +105 to +106
STORM_LOG_THROW(threshold >= 0, storm::exceptions::NotSupportedException,
"Lower reward bound in dimension " << formulaDim << " is not satisfiable.");
Comment on lines +34 to +38
for (uint64_t state = 0; state < transitionMatrix.getRowGroupCount(); ++state) {
for (auto choice : transitionMatrix.getRowGroupIndices(state)) {
for (auto const& entry : transitionMatrix.getRow(choice)) {
auto const obs = transitionObservationFunction(state, choice, entry.getColumn());
transitionTargetObservations.push_back(obs);
Comment thread src/storm-pomdp/beliefs/verification/BeliefBasedModelChecker.cpp

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants